package org.example.testAtomicInteger;


import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntBinaryOperator;

/**
 * 使用轮询（Round-Robin）策略从目标列表中选择一个条目。
 * 支持基于 key 的独立轮询状态，线程安全。
 */
public class Demotest1 {

    // 存储每个 key 对应的轮询位置（线程安全的映射）
    private static final ConcurrentHashMap<String, AtomicInteger> positionMap = new ConcurrentHashMap<>();

    /**
     * 根据指定的 key，从目标列表中按轮询策略选择一个目标。
     *
     * @param key     用于标识轮询上下文的键（例如客户端ID、服务名等）
     * @param targets 目标列表（如服务器地址、任务节点等）
     * @return 被选中的目标字符串
     * @throws IllegalArgumentException 如果目标列表为空或为 null
     */
    public static String roundRobin(String key, List<String> targets) {
        // 参数校验：确保目标列表有效
        if (targets == null || targets.isEmpty()) {
            throw new IllegalArgumentException("目标列表不能为空");
        }

        // 获取该 key 对应的轮询计数器，若不存在则初始化为 0
        AtomicInteger position = positionMap.computeIfAbsent(key, k -> new AtomicInteger(0));

        // 定义累加操作：将当前位置 +1，并对列表大小取模，实现循环
        IntBinaryOperator modIncrement = (currentIndex, increment) -> (currentIndex + increment) % targets.size();

        // 原子性地获取当前索引并更新为下一个位置（取模循环）
        int currentIndex = position.getAndAccumulate(1, modIncrement);

        // 返回当前索引对应的目标
        return targets.get(currentIndex);
    }

    public static void main(String[] args) {
        List<String> targets = Arrays.asList("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L");
        String key = "service_group";

        // 连续调用8次
        for (int i = 0; i < 8; i++) {
            System.out.println(roundRobin(key, targets) + " ");
        }
    }
}